package com.myapp.tools.msgbuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.myapp.tools.msgbuilder.base.BeanBean;
import com.myapp.tools.msgbuilder.base.FieldBean;
import com.myapp.tools.msgbuilder.base.MsgBean;

public class MsgParse {

	// 日志
	private Logger log = Logger.getLogger(MsgParse.class);

	private MsgBuilder msgBuilder = new MsgBuilder();

	public void parsePath(File filePath) {
		if (filePath.isDirectory()) {
			File[] files = filePath.listFiles();
			for (File file : files) {
				if (".svn".startsWith(file.getName())) {
					continue;
				}
				if (file.isDirectory()) {
					this.parsePath(file);
				} else {
					this.parseFile(file.getAbsolutePath());
				}
			}

			// 生成消息所有消息
			msgBuilder.builderClientAllMessage();
		}
	}

	private void parseFile(String path) {
		InputStream is = null;
		Reader re = null;
		try {
			is = new FileInputStream(path);
			re = new InputStreamReader(is, "UTF-8");
			SAXBuilder builder = new SAXBuilder(false);
			Document document = builder.build(re);
			Element root = document.getRootElement();

			// 解析package
			String msgPackage = root.getAttributeValue("msgPackage");
			String logicalPackage = root.getAttributeValue("logicalPackage");

			// 解析消息
			@SuppressWarnings("unchecked")
			List<Element> msgsList = root.getChildren("message");
			List<MsgBean> msgs = this.parseMsgBean(msgsList);

			// 生成消息
			msgBuilder.builderMsg(msgPackage, logicalPackage, msgs);
		} catch (FileNotFoundException e) {
			log.error(String.format("Can't find File[%s]", path), e);
			System.exit(1);
		} catch (UnsupportedEncodingException e) {
			log.error(String.format("Unsupported Encoding - File[%s]", path), e);
			System.exit(1);
		} catch (IOException e) {
			log.error(String.format("Read error - File[%s]", path), e);
			System.exit(1);
		} catch (JDOMException e) {
			log.error(String.format("Parse error - File[%s]", path), e);
			System.exit(1);
		} finally {
			try {
				if (re != null) {
					re.close();
					re = null;
				}
			} catch (Exception e) {
			}

			try {
				if (is != null) {
					is.close();
					is = null;
				}
			} catch (Exception e) {
			}
		}
	}

	@SuppressWarnings("unchecked")
	private List<MsgBean> parseMsgBean(List<Element> msgsList) {
		List<MsgBean> msgs = new ArrayList<MsgBean>();
		MsgBean msgBean;
		for (Element msg : msgsList) {
			msgBean = new MsgBean();

			// 解析bean
			List<Element> beanList = msg.getChildren("bean");
			List<BeanBean> beans = this.parseBeans(beanList);
			msgBean.setBeans(beans);

			// 解析field
			List<Element> fieldsList = msg.getChildren("field");
			List<FieldBean> fields = this.parseFields(fieldsList);
			msgBean.setFiles(fields);

			// 解析消息类型
			msgBean.setType(msg.getAttributeValue("type"));

			// 解析名字
			msgBean.setName(msg.getAttributeValue("name"));

			// 解析消息id
			msgBean.setId(msg.getAttributeValue("id"));

			// 解析注释
			msgBean.setComment(msg.getAttributeValue("comment"));

			// 解析使用权限
			msgBean.setPermission(msg.getAttributeValue("permission"));

			msgs.add(msgBean);
		}
		return msgs;
	}

	private List<BeanBean> parseBeans(List<Element> beanList) {
		List<BeanBean> beans = new ArrayList<BeanBean>();
		BeanBean beanBean = null;
		for (Element bean : beanList) {
			beanBean = new BeanBean();
			String clazz = bean.getAttributeValue("class");
			beanBean.setClazz(clazz);

			String clazzShort = clazz.substring(clazz.lastIndexOf(".") + 1);
			beanBean.setClazzShort(clazzShort);

			String name = bean.getAttributeValue("name");
			beanBean.setName(name);

			String comment = bean.getAttributeValue("comment");
			beanBean.setComment(comment);

			String list = bean.getAttributeValue("list");
			beanBean.setList(list);

			@SuppressWarnings("unchecked")
			List<Element> fieldsList = bean.getChildren("field");
			List<FieldBean> fieldsBean = this.parseFields(fieldsList);
			beanBean.setFieldsBean(fieldsBean);
			beans.add(beanBean);
		}
		return beans;
	}

	private List<FieldBean> parseFields(List<Element> fields) {
		List<FieldBean> fieldsBean = new ArrayList<FieldBean>();
		for (Element field : fields) {
			fieldsBean.add(this.parseField(field));
		}
		return fieldsBean;
	}

	private FieldBean parseField(Element field) {
		FieldBean fieldBean = new FieldBean();

		String type = field.getAttributeValue("type");
		fieldBean.setType(type);

		String name = field.getAttributeValue("name");
		fieldBean.setName(name);

		String comment = field.getAttributeValue("comment");
		fieldBean.setComment(comment);

		return fieldBean;
	}
}
